package com.xique.park.service.biz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.xique.common.core.constant.Constants;
import com.xique.common.core.constant.UserConstants;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.park.bean.domain.*;
import com.xique.park.bean.domain.wechat.WxMessageTemplate;
import com.xique.park.bean.dto.ParkInTemplateDTO;
import com.xique.park.bean.dto.ParkOutTemplateDTO;
import com.xique.park.bean.dto.PaymentTemplateDTO;
import com.xique.park.bean.search.wechat.WxMessageTemplateListSearch;
import com.xique.park.bean.transform.wechat.WechatSendTemplateTransform;
import com.xique.park.constant.BaseUserConstants;
import com.xique.park.constant.WxMessageTemplateConstants;
import com.xique.park.service.biz.service.IParkWxMessageSendBizService;
import com.xique.park.service.service.*;
import com.xique.park.utils.WechatUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: xq-cloud
 * @ClassName ParkInFinishWxSendBizServiceImpl
 * @description:
 * @author: HdongSun
 * @create: 2022-08-26 13:51
 **/
@Service
@Slf4j
@RequiredArgsConstructor
public class ParkWxMessageSendBizServiceImpl implements IParkWxMessageSendBizService {

    @Value("${wx.gzh.appId}")
    private String appId;

    @Value("${wx.gzh.secret}")
    private String secret;

    private final WechatUtils wechatUtils;

    private final IBaseUserService baseUserService;

    private final IParkInfoService parkInfoService;

    private final IWxMessageTemplateService wxMessageTemplateService;

    private final IUserCarService userCarService;

    private final IParkInService parkInService;

    @Override
    public void delayParkInFinishProcess(ParkIn parkIn) {
        /**
         * TODO
         * 1.查询到车牌对应的用户
         * 2.查询该用户是否关注了公众号
         * 3.更具公众号openid推送入场信息
         * */
        Map<String, Object> params = before(parkIn.getInCarPlate(), parkIn.getParkId(), WxMessageTemplateConstants.Type.PARK_IN_TEMPLATE);
        if (MapUtil.isEmpty(params)) {
            return;
        }

        ParkInTemplateDTO dto = WechatSendTemplateTransform.transformParkInTemplate((WxMessageTemplate) params.get("template"), parkIn.getInCarPlate(), params.get("park_name").toString(), parkIn.getInTime());
        params.put("data", JSONObject.parseObject(JSONObject.toJSONString(dto)));

        AjaxResult result = wechatUtils.sendMessageV1(appId, secret, params);

//        log.info("【停车微信公众号推送】推送结果：appid:{}, 参数:{}, result:{}", appId, params, result.get(AjaxResult.MSG_TAG).toString());
    }

    @Override
    public void delayParkOutFinishProcess(ParkOut parkOut) {
        if ("214".equals(parkOut.getStatus())) {
            log.error("【停车微信公众号推送】-代缴费不推送，parkOut:{}", parkOut);
            return;
        }

        Map<String, Object> params = before(parkOut.getOutCarPlate(), parkOut.getParkId(), WxMessageTemplateConstants.Type.PARK_OUT_TEMPLATE);
        if (MapUtil.isEmpty(params)) {
            return;
        }

        ParkIn parkIn = parkInService.selectParkInById(parkOut.getInId());

        ParkOutTemplateDTO dto = WechatSendTemplateTransform.transformParkOutTemplate((WxMessageTemplate) params.get("template"), parkOut.getOutCarPlate(), params.get("park_name").toString(), parkIn.getInTime(), parkOut.getOutTime(), parkOut.getActualFee());
        params.put("data", JSONObject.parseObject(JSONObject.toJSONString(dto)));

        AjaxResult result = wechatUtils.sendMessageV1(appId, secret, params);

//        log.info("【停车微信公众号推送】推送结果：appid:{}, 参数:{}, result:{}", appId, params, result.get(AjaxResult.MSG_TAG).toString());
    }

    @Override
    public void delayPaymentProcess(ParkingOrderOn parkingOrderOn) {
        Map<String, Object> params = before(parkingOrderOn.getPlate(), parkingOrderOn.getParkId(), WxMessageTemplateConstants.Type.PAYMENT_TEMPLATE);
        if (MapUtil.isEmpty(params)) {
            return;
        }

        PaymentTemplateDTO dto = WechatSendTemplateTransform.transformPaymentTemplate((WxMessageTemplate) params.get("template"), parkingOrderOn.getPlate(), params.get("park_name").toString(), parkingOrderOn.getParkingTime(), parkingOrderOn.getCouponFee(), parkingOrderOn.getTotalFee(), parkingOrderOn.getInTime());
        params.put("data", JSONObject.parseObject(JSONObject.toJSONString(dto)));

        AjaxResult result = wechatUtils.sendMessageV1(appId, secret, params);

//        log.info("【停车微信公众号推送】推送结果：appid:{}, 参数:{}, result:{}", appId, params, result.get(AjaxResult.MSG_TAG).toString());
    }

    private Map<String, Object> before(String plate, Long parkId, Integer type) {
        Map<String, Object> params = new HashMap<>();
        ParkInfo project = parkInfoService.getById(parkId);
//        log.info("【微信公众号推送】项目信息：parkId:{}, project:{}", parkId, project);
        if (ObjectUtil.isEmpty(project)) {
            return null;
        }
        params.put("park_id", parkId);
        params.put("park_name", project.getName());

        UserCar userCarSearch = new UserCar();
        userCarSearch.setPlate(plate);
        List<UserCar> userCarList = userCarService.selectUserCarList(userCarSearch);
        if (CollUtil.isEmpty(userCarList)) {
            log.error("【停车微信公众号推送】-未找到该车牌号的用户信息，plate:{}", plate);
            return null;
        }
        UserCar userCar = userCarList.get(0);
        Long baseUserId = userCar.getUserId();

        if (StringUtils.isNull(baseUserId)) {
            log.error("【停车微信公众号推送】-用户id为空，base_user_id:{}", baseUserId);
            return null;
        }
        BaseUser baseUser = baseUserService.selectBaseUserById(baseUserId);
        if (ObjectUtil.isEmpty(baseUser)) {
            log.error("【停车微信公众号推送】-未找到对应的用户信息，base_user_id:{}, base_user:{}", baseUserId, baseUser);
            return null;
        }
        log.info("【停车微信公众号推送】用户基础信息：{}", baseUser);
        Integer pushStatus = baseUser.getPushStatus();
        if (BaseUserConstants.PushStatus.PUSH_STATUS_CLOSE == pushStatus) {
            log.error("【停车微信公众号推送】-用户推送功能关闭，base_user_id:{}, base_user:{}", baseUserId, baseUser);
            return null;
        }
        String openId = baseUser.getWechatGzOpenid();
        if (StringUtils.isEmpty(openId)) {
            log.error("【停车微信公众号推送】-微信公众号openid为空，base_user_id:{}, base_user:{}, openid:{}", baseUserId, baseUser, openId);
            return null;
        }
        params.put("openid", openId);
        WxMessageTemplateListSearch search = new WxMessageTemplateListSearch();
        search.setType(type);
        search.setStatus(Constants.NORMAL);
        List<WxMessageTemplate> list = wxMessageTemplateService.selectTemplateList(search);
//        log.info("【停车微信公众号推送】推送模板：{}", list);
        if (CollUtil.isEmpty(list)) {
            log.error("【停车微信公众号推送】-推送模板为空，list:{}", list);
            return null;
        }
        WxMessageTemplate template = list.get(0);
        String templateId = template.getTemplateId();
        params.put("template", template);

        Map<String, Object> miniprogram = new HashMap<>(2);
        miniprogram.put("appid", template.getMiniAppId());
        miniprogram.put("pagepath", template.getPagepath());

        String url = template.getUrl();
        if (WxMessageTemplateConstants.JumpType.NONE == template.getJumpType()) {
            url = null;
            miniprogram = null;
        }
        if (WxMessageTemplateConstants.JumpType.URL == template.getJumpType()) {
            miniprogram = null;
        }
        if (WxMessageTemplateConstants.JumpType.MINIPROGRAM == template.getJumpType()) {
            url = null;
        }
//        log.info("【停车微信公众号推送】推送参数：appid:{}, openid:{}, templateId:{}, url:{}, miniprogram:{}", appId, openId, templateId, url, miniprogram);

        params.put("touser", openId);
        params.put("template_id", templateId);
        params.put("url", url);
        params.put("miniprogram", miniprogram);

        return params;
    }
}
